###################### 面向对象

#定义一个基类
class Person(object):
    pass;

class People(object):
    pass;

#多重继承
class Who(Person, People):
    pass;

#定义一个类，并继承自一个基类object
class Student(Person):

    '''
    类属性，也就是静态属性，通过Student.name访问，
    注意：如果访问s.name，则访问的首先是对象属性，无则访问静态属性
    s.name=2直接定义了一个对象属性，会覆盖类属性name
    '''
    name='Student'

    '''
    静态方法（类方法）：不传入self就是类方法，Student.length(bart)
    '''
    def length(obj):
        return len(obj)

    #构造方法：通过s = Student(name, score)来调用
    def __init__(self, name, score):
        self.name = name;
        self.score = score;
        self.__age = 23;

    #特殊方法len，通过len(s)来调用
    def __len__(self):
        return 100

    #print(s)时，会调用这个方法，如果不重写，默认的实现是输出类似<__main__.Student object at 0x109afb190>的字符串
    def __str__(self):
        return "I'm a student, my name is %s" %self.name

    #这个方法会在命令行界面输入s时，调用此方法来输出，专门给调试用的，下面是偷懒的写法
    __repr__ = __str__

    #
    def __getattr__(self, path=''):
        return '不存在的属性'

    #===访问私有属性：私有属性就是以双下划线开头的属性
    def getAge(self):
        return self.__age;

    def setAge(self, age):
        self.__age = age;
    #===over

    def toString(self):
        print('%s: %s' % (self.name, self.score));

    def getGrade(self):
        if(self.score >= 80):
            return 'A';
        elif self.score >= 60:
            return 'B';
        else:
            return 'C';

#定义一个类，什么没有
class NoStudent(object):
    pass

#创建对象，调用方法
bart = Student('Bart Simpson', 59);
bart.toString();
print(bart);
print(Student);

#访问属性
bart.name = "Jack";
bart.toString();

bart.score = 80;
print(bart.getGrade());

bart.score = 40;
print(bart.getGrade());

#访问私有属性
bart.setAge(23);
print(bart.getAge())
print(bart._Student__age);#暴力访问私有属性，不建议这么干，因为此名字并无统一规范，依赖于机器和实现

# 访问特殊属性：双下划线结尾
print(len(bart))  #其实调用了特殊方法：__len__，字符串，列表都是这个道理，所以你的类型如果需要响应len方法调用，只需要实现__len__方法

# 访问静态成员：
print(Student.name)
print(Student.length(bart))


#添加无限制属性
bart.nnn = "dd";
print(bart.nnn);
